package com.zq.thread.Observe;

/**
 * @Author: zhaoqi
 * @Date: 2020/5/23 22:56
 * @Version 1.0
 */

public class ObservableThread<T> extends Thread implements Observable {

    private final TaskLifececle<T> lifececle;
    private final Task<T> task;
    private Cycle cycle;

    public ObservableThread(Task<T> task) {
        this(new TaskLifececle.EmptyLifecycle<>(),task);
    }

    public ObservableThread(TaskLifececle<T> lifececle, Task<T> task) {
        super();
        if (task ==null){
            throw new IllegalArgumentException("the task is requires.");
        }
        this.lifececle = lifececle;
        this.task = task;
    }

    @Override
    public final void run() {
        // 执行线程逻辑单元的时候，分别触发相应的事件
        this.update(Cycle.STARTED,null,null);
        try {
            this.update(Cycle.RUNABLE,null,null);
            T call = this.task.call();
            this.update(Cycle.DONE,null,null);
        } catch (Exception e){
            this.update(Cycle.ERROR,null,null);
        }
    }

    private void update(Cycle cycle, T result, Exception e) {
        this.cycle = cycle;
        if (lifececle == null){
            return;
        }

        try {
            switch (cycle){
                case STARTED:
                    this.lifececle.onStart(currentThread());
                    break;
                case RUNABLE:
                    this.lifececle.onRunning(currentThread());
                    break;
                case DONE:
                    this.lifececle.onFinish(currentThread(),result);
                    break;
                case ERROR:
                    this.lifececle.onError(currentThread(),e);
                    break;
            }
        } catch (Exception ex) {
            if (cycle == Cycle.ERROR){
                throw ex;
            }
        }


    }

    @Override
    public Cycle getCycle() {
        return this.cycle;
    }

    @Override
    public void interrput() {
        this.interrput();
    }
}
